const fs = require('fs')
const mongoose = require('mongoose')
const boom = require('boom')
const del = require('del')

const Book = require('../models/book')
const {
  eBook
} = require('../utils/book')

const environment = process.env.NODE_ENV
const stage = require('../config')[environment]

module.exports = {
  create: (req, res, next) => {
    mongoose.connect(process.env.MONGOLAB_URI, stage.mongo_options).then(
      () => {
        let result = {}
        let status = 201
        if (!req.file || req.file.length === 0) {
          return next(boom.badImplementation(err))
        } else {
          const ebook = new eBook(req.file)
          ebook.parse().then(ebook => {
              const book = new Book(ebook)
              book.save((err, book) => {
                if (err) {
                  mongoose.connection.close()
                  return next(boom.badImplementation(err))
                }
                result.status = status
                result.data = book
                mongoose.connection.close()
                return res.status(status).send(result)
              })
            })
            .catch((err) => {
              return next(boom.badImplementation(err))
              // book.reset()
            })
        }
      },
      err => {
        mongoose.connection.close()
        return next(boom.badImplementation(err))
      }
    )
  },
  delete: (req, res, next) => {
    mongoose.connect(process.env.MONGOLAB_URI, stage.mongo_options).then(
      () => {
        let result = {}
        let status = 200
        const {
          id
        } = req.params
        Book.findByIdAndDelete(id).
        exec(function (err, book) {
          if (err) {
            mongoose.connection.close()
            return next(boom.badImplementation(err))
          }
          del.sync([`${process.env.UPLOAD_PATH}/${book.file_path}`, `${process.env.UPLOAD_PATH}/${book.cover_path}`])
          result.status = status
          result.data = book
          mongoose.connection.close()
          return res.status(status).send(result)
        })
      },
      err => {
        mongoose.connection.close()
        return next(boom.badImplementation(err))
      }
    )
  },
  update: (req, res, next) => {
    mongoose.connect(process.env.MONGOLAB_URI, stage.mongo_options).then(
      () => {
        let result = {}
        let status = 200
        const {
          id
        } = req.params
        Book.findByIdAndUpdate(id, req.body).
        exec(function (err, book) {
          if (err) {
            mongoose.connection.close()
            return next(boom.badImplementation(err))
          }
          result.status = status
          result.data = book
          mongoose.connection.close()
          return res.status(status).send(result)
        })
      },
      err => {
        mongoose.connection.close()
        return next(boom.badImplementation(err))
      }
    )
  },
  show: (req, res, next) => {
    mongoose.connect(process.env.MONGOLAB_URI, stage.mongo_options).then(
      () => {
        let result = {}
        let status = 200
        const {
          id
        } = req.params
        Book.findById(id).
        exec(function (err, book) {
          if (err) {
            mongoose.connection.close()
            return next(boom.badImplementation(err))
          }
          book.cover_path = `${process.env.UPLOAD_URL}${book.cover_path}`
          book.file_path = `${process.env.UPLOAD_URL}${book.file_path}`
          result.status = status
          result.data = book
          mongoose.connection.close()
          return res.status(status).send(result)
        })
      },
      err => {
        mongoose.connection.close()
        return next(boom.badImplementation(err))
      }
    )
  },
  index: (req, res, next) => {
    mongoose.connect(process.env.MONGOLAB_URI, stage.mongo_options).then(
      () => {
        let result = {}
        let status = 200
        let {
          feature,
          category,
          search,
          page = 1,
          pagesize = 20
        } = req.query

        // condition
        let condition = {}
        if (category) { //分类
          condition.category = category
        } else if (search) { //搜索
          condition = {
            $or: [{
                title: {
                  $regex: search,
                  $options: '$i' // 忽略大小写
                }
              },
              {
                author: {
                  $regex: search,
                  $options: '$i' // 忽略大小写
                }
              }
            ]
          }
        } else if (feature === 'recommend') { //推荐
          condition.recommend = true
          page = 1
          pagesize = 8
        }

        // sort
        let sort = {}
        if (feature === 'new') { //新上架
          sort = {
            created_at: -1,
            updated_at: -1
          }
          page = 1
          pagesize = 8
        } else if (feature === 'rank') { //豆瓣评分
          sort = {
            rank: -1
          }
          page = 1
          pagesize = 8
        } else {
          sort = {
            created_at: -1,
            updated_at: -1
          }
        }

        // page and pagesize
        page = Number(page)
        pagesize = Number(pagesize)
        let num = (page - 1) * pagesize

        // find
        Book.find(condition).
        sort(sort).
        skip(num).
        limit(pagesize).
        exec(function (err, books) {
          if (err) {
            mongoose.connection.close()
            return next(boom.badImplementation(err))
          }
          books.forEach(book => book.cover_path = `${process.env.UPLOAD_URL}${book.cover_path}`)
          books.forEach(book => book.file_path = `${process.env.UPLOAD_URL}${book.file_path}`)
          result.status = status
          result.data = books
          mongoose.connection.close()
          return res.status(status).send(result)
        })
      },
      err => {
        mongoose.connection.close()
        return next(boom.badImplementation(err))
      }
    )
  }
}
